package com.xnx3.kefu.core.util;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.BeanUtils;

import com.xnx3.j2ee.service.SqlCacheService;
import com.xnx3.j2ee.util.CacheUtil;
import com.xnx3.j2ee.util.ConsoleUtil;
import com.xnx3.j2ee.util.IpUtil;
import com.xnx3.j2ee.util.SpringUtil;
import com.xnx3.kefu.core.bean.ChatUserBean;
import com.xnx3.kefu.core.entity.Zuoxi;

/**
 * {@link User} 工具类
 * @author 管雷鸣
 *
 */
public class UserUtil {
	//根据userid来取游客的user信息。只是游客的在这里取，已登录用户的直接从缓存的实体类取
	//public static final String USER_BIND = "kefu:youke:useridBind:{userid}";
	// 根据chatid来取用户的ChatUserBean信息。游客跟客服坐席都是在这里 (2020.5.9日以前是：根据chatid来取游客的user信息。只是游客的在这里取，已登录用户的直接从缓存的实体类取)
	// 2023.11 更改缓存时间为60天
	public static final String CHATID_BIND = "kefu:youke:chatidBind:{chatid}";
	public static final int CHATID_BIND_EXPIRATIONTIME = 5184000; //60天，单位是秒，缓存过期时间
	
	
	/**
	 * 绑定ChatUserBean，可以根据chatid来取 ChatUserBean。 这里游客才会真的进行绑定。如果是已登录用户会自动忽略
	 * @param user
	 */
	public static void bind(ChatUserBean chatUser){
		if(chatUser == null){
			return;
		}
		if(isYouke(chatUser.getChatid())){
			//根据token取user
			CacheUtil.set(CHATID_BIND.replace("{chatid}", chatUser.getChatid()), chatUser, CHATID_BIND_EXPIRATIONTIME);
		}
	}
	
	/**
	 * 通过客服坐席的id，获取 {@link ChatUserBean} 信息
	 * @param chatid {@link Zuoxi}.id（原先是  {@link User}.id ）
	 * @return 理论上不可能会返回null。如果出现空指针，要检查逻辑
	 * 			（但是如果改动了缓存的对象属性，造成序列化出错，就会返回null）
	 */
	public static ChatUserBean getUser(String chatid){
		ChatUserBean chatUser = null;
		Object obj = CacheUtil.get(CHATID_BIND.replace("{chatid}", chatid));
		if(obj != null){
			chatUser = (ChatUserBean)obj;
			return chatUser;
		}
		if(!isYouke(chatid)){
			//非游客，那就是正常的客服坐席
			
			//已登录用户，那么直接从缓存取User实体类
			SqlCacheService sqlCacheService = SpringUtil.getSqlCacheService();
			//先获取坐席信息
			Zuoxi zuoxi = sqlCacheService.findById(Zuoxi.class, chatid);
			if(zuoxi == null){
				//坐席不存在
				ConsoleUtil.error("坐席不存在！chatid:"+chatid);
			}else{
				com.xnx3.j2ee.entity.User dbUser = sqlCacheService.findById(com.xnx3.j2ee.entity.User.class, zuoxi.getUserid());
				if(dbUser != null){
					if(obj == null){
						//如果Cache缓存中还没有 ChatUserBean 缓存，那么创建一个并缓存
						chatUser = new ChatUserBean();
						chatUser.setUser(dbUser);
						//加入缓存
						CacheUtil.set(CHATID_BIND.replace("{chatid}", chatid), chatUser, CHATID_BIND_EXPIRATIONTIME);
					}else{
						chatUser.setUser(dbUser);
					}
				}
			}
		}
		
		/*
		 * 
		 * user不可能为null，除非传入的id不对。如果实际使用中出现空指针，那么逻辑出现问题，需要筛查逻辑
		 * 
		 */
		
		return chatUser;
	}
	

	/**
	 * 更新 chat 对应的 ChatUserBean 数据。 这里更新的主要就是 getUser(chatid) 获取的数据
	 * @param chatid {@link Zuoxi}.id
	 * @param chatUserBean {@link ChatUserBean} 要更新的数据。这个数据是先从 getUser(chatid) 获取，修改后再传入
	 */
	public static void updateUser(String chatid, ChatUserBean chatUserBean){
		if(chatid == null){
			return;
		}
		String key = CHATID_BIND.replace("{chatid}", chatid);
		CacheUtil.set(key, chatUserBean, CHATID_BIND_EXPIRATIONTIME);
	}
	
	
	/**
	 * 判断用户id是游客还是已登录用户
	 * @param id user.chatid
	 * @return true:游客， false:已登录用户
	 */
	public static boolean isYouke(String chatid){
		if(chatid == null || chatid.length() != 32){
			return true;
		}
		return false;
	}
	
	/**
	 * 判断一个字符串是否是数字
	 * @param str
	 * @return true:是数字
	 */
	public static boolean isNumber(String str){
		Pattern pattern = Pattern.compile("[0-9]*");
		Matcher isNum = pattern.matcher(str);
		if(!isNum.matches()){
			return false;
		}else{
			return true;
		}
	}
	
	/**
	 * 这里是过滤掉 {@link ChatUserBean} 中的浏览器信息，比如ip、url、useragent 等。
	 * 这里返回的信息是给访客看的，所以么必要吧客服坐席的信息给暴露
	 * @param bean
	 * @return
	 */
	public static ChatUserBean filterBrowserInfo(ChatUserBean bean){
		if(bean == null) {
			return null;
		}
		
		ChatUserBean user = new ChatUserBean();
		BeanUtils.copyProperties(bean, user);
		
		user.setIp("");
		user.setRefererUrl("");
		user.setUrl("");
		user.setUserAgent("");
		return user;
	}
	
	/**
	 * 将访客的浏览器信息记录
	 * @param bean
	 * @param request
	 * @return
	 */
	public static ChatUserBean setBrowserInfo(ChatUserBean bean, HttpServletRequest request) {
		if(bean == null) {
			return null;
		}
		bean.setIp(IpUtil.getIpAddress(request));
		bean.setRefererUrl(request.getHeader("Referer"));
		bean.setUserAgent(request.getHeader("User-Agent"));
		bean.setUrl(request.getHeader("Origin"));
		return bean;
	}
}
